home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_13_11 / phillip2 / scale.c < prev    next >
C/C++ Source or Header  |  1993-06-25  |  18KB  |  559 lines

  1.  
  2.  
  3.     /***********************************************
  4.     *
  5.     *       file d:\cips\scale.c
  6.     *
  7.     *       Functions: This file contains
  8.     *          zoom_image_array
  9.     *          shrink_image_array
  10.     *          interpolate_pixel
  11.     *          average_pixel
  12.     *          median_pixel
  13.     *          get_scaling_options
  14.     *          blank_image_array
  15.     *
  16.     *       Purpose:
  17.     *          These functions implement image array
  18.     *          zooming (enlarging) and shrinking.
  19.     *
  20.     *       External Calls:
  21.     *          wtiff.c - round_off_image_size
  22.     *                    create_file_if_needed
  23.     *                    write_array_into_tiff_image
  24.     *          tiff.c - read_tiff_header
  25.     *          rtiff.c - read_tiff_image
  26.     *          numcvrt.c - get_integer
  27.     *          filter.c - median_of
  28.     *
  29.     *       Modifications:
  30.     *          8 April 1992 - created
  31.     *
  32.     *************************************************/
  33.  
  34. #include "cips.h"
  35.  
  36.      /*******************************************
  37.      *
  38.      *   zoom_image_array(...
  39.      *
  40.      *   This function zooms in on an input
  41.      *   image array.  It zooms by enlarging
  42.      *   an input image array and writing the
  43.      *   resulting image arrays to an output
  44.      *   image file.  It can zoom or enlarge by
  45.      *   a factor of 2 or 4.
  46.      *
  47.      *   You can zoom or enlarge an image array
  48.      *   by using either the replication or
  49.      *   interpolation methods.
  50.      *
  51.      *******************************************/
  52.  
  53.  
  54. zoom_image_array(in_name, out_name, the_image, out_image,
  55.           il, ie, ll, le, scale, method)
  56.    char   in_name[], out_name[], method[];
  57.    int    il, ie, ll, le, scale;
  58.    short  the_image[ROWS][COLS],
  59.           out_image[ROWS][COLS];
  60. {
  61.    int    A, B, a, b, count, factor, 
  62.           i, j, length, width;
  63.    struct tiff_header_struct image_header;
  64.  
  65.            /******************************************
  66.            *
  67.            *   Check the scale factor.  If it is not
  68.            *   a valid factor (2 or 4), then set
  69.            *   it to 2.
  70.            *
  71.            ******************************************/
  72.  
  73.    factor = scale;
  74.    if(factor != 2 &&
  75.       factor != 4) factor = 2;
  76.  
  77.    create_file_if_needed(in_name, out_name, out_image);
  78.  
  79.       /*******************************************
  80.       *
  81.       *   Let me try to explain the nested loops
  82.       *   shown below.
  83.       *
  84.       *   We will enlarge the_image by the factor.
  85.       *   Therefore, we want to divide the_image
  86.       *   into parts of size ROWS/factor by
  87.       *   COLS/factor.  We will loop through
  88.       *   the_image parts ROWS/factor and COLS/factor
  89.       *   using the loops over i and j.
  90.       *
  91.       *   We divided the_image into parts so we must
  92.       *   include all of these parts.  That is why we
  93.       *   do the loops over A and B.  There are
  94.       *   factor*factor parts.
  95.       *
  96.       *   Finally, we do the loops over a and b.
  97.       *   We must replicate every element in the_image
  98.       *   factor*factor times and put these into
  99.       *   out_image.  The a and b loops perform this
  100.       *   task.
  101.       *
  102.       *   The equations inside the []'s for
  103.       *   the_image and out_image are also confusing.
  104.       *   If you work them out, you'll see that we
  105.       *   are bouncing through the image arrays
  106.       *   and fitting the pixels into the right
  107.       *   places.
  108.       *
  109.       *   The final proof is that this works.
  110.       *
  111.       *   One final note:  the factor should divide
  112.       *   evenly into ROWS.  For example, ROWS=100
  113.       *   so using a factor of 8 is not good.
  114.       *   100/8 = 12.5 and this leave you with
  115.       *   an empty strip along the right and
  116.       *   bottom edges of the out_image.
  117.       *
  118.       *******************************************/
  119.  
  120.            /*****************************************
  121.            *
  122.            *   Replication method
  123.            *
  124.            ******************************************/
  125.  
  126.    if(method[0] == 'r' || method[0] == 'R'){
  127.       read_tiff_image(in_name, the_image, 
  128.                       il, ie, ll, le);
  129.       count = 1;
  130.       for(A=0; A<factor; A++){
  131.        for(B=0; B<factor; B++){
  132.         for(i=0; i<ROWS/factor; i++){
  133.          for(j=0; j<COLS/factor; j++){
  134.           for(a=0; a<factor; a++){
  135.            for(b=0; b<factor; b++){
  136.              out_image[factor*i+a][factor*j+b] =
  137.               the_image[i+A*ROWS/factor][j+B*COLS/factor];
  138.            }  /* ends loop over b */
  139.           }  /* ends loop over a */
  140.          }  /* ends loop over j */
  141.         }  /* ends loop over i */
  142.         printf("\nzooming replication %3d of %3d",
  143.                count++, factor*factor);
  144.         write_array_into_tiff_image(out_name, out_image,
  145.             1+A*ROWS, 1+B*COLS, 101+A*ROWS, 101+B*COLS);
  146.        }  /* ends loop over B */
  147.       }  /* ends loop over A */
  148.    }  /* ends replication method */
  149.  
  150.            /***************************
  151.            *
  152.            *   Interpolation method
  153.            *
  154.            ****************************/
  155.  
  156.    if(method[0] == 'i' || method[0] == 'I'){
  157.       read_tiff_image(in_name, the_image,
  158.                       il, ie, ll, le);
  159.       count = 1;
  160.       for(A=0; A<factor; A++){
  161.          for(B=0; B<factor; B++){
  162.           for(i=0; i<ROWS/factor; i++){
  163.            for(j=0; j<COLS/factor; j++){
  164.             for(a=0; a<factor; a++){
  165.              for(b=0; b<factor; b++){
  166.                 out_image[factor*i+a][factor*j+b] =
  167.                   interpolate_pixel(the_image, A, B,
  168.                               i, j, a, b, factor);
  169.              }  /* ends loop over b */
  170.             }  /* ends loop over a */
  171.            }  /* ends loop over j */
  172.           }  /* ends loop over i */
  173.        printf("\nzooming interpolation %3d of %3d",
  174.                      count++, factor*factor);
  175.        write_array_into_tiff_image(out_name, out_image,
  176.                  1+A*ROWS, 1+B*COLS,
  177.                  101+A*ROWS, 101+B*COLS);
  178.      }  /* ends loop over B */
  179.     }  /* ends loop over A */
  180.    }  /* ends interpolation method */
  181.  
  182.  
  183. }  /* ends zoom_image_array */
  184.  
  185.  
  186.  
  187.  
  188.  
  189.     /***********************************************
  190.     *
  191.     *    interpolate_pixel(...
  192.     *
  193.     *    This function interpolates between pixel
  194.     *    values and returns the interlopated value.
  195.     *
  196.     ***********************************************/
  197.  
  198. interpolate_pixel(the_image, A, B, i, j, a, b, factor)
  199.    int   A, B, a, b, factor, i, j;
  200.    short the_image[ROWS][COLS];
  201. {
  202.    int   num, x = 0, y = 0;
  203.    short diff, result;
  204.  
  205.    if(a > 0) y = 1;
  206.    if(b > 0) x = 1;
  207.    diff = 
  208.       the_image[y+i+A*ROWS/factor][x+j+B*COLS/factor] -
  209.       the_image[i+A*ROWS/factor][j+B*COLS/factor];
  210.  
  211.           /******************************************
  212.           *
  213.           * If you are at the edge of the input image
  214.           * array, then you cannot interpolate to the
  215.           * next point because there is no next point.
  216.           * Therefore, set the diff to 0.
  217.           *
  218.           *******************************************/
  219.  
  220.    if((y+i+A*ROWS/factor) >= ROWS) diff = 0;
  221.    if((x+j+B*COLS/factor) >= COLS) diff = 0;
  222.  
  223.    num = a+b;
  224.    if(num > factor) num = factor;
  225.    result = the_image[i+A*ROWS/factor][j+B*COLS/factor] +
  226.             num*diff/factor;
  227.    return(result);
  228. }  /* ends interpolate_pixel */
  229.  
  230.  
  231.  
  232.  
  233.  
  234.      /*******************************************
  235.      *
  236.      *   shrink_image_array(...
  237.      *
  238.      *   This function shrinks a part of an
  239.      *   image.  It takes a part of an input
  240.      *   image (described by il1, ie1, ll1, le1)
  241.      *   shrinks a 200x200 or 400x400 area down
  242.      *   to a 100x100 array, and writes this result
  243.      *   to an output file.  The location in the
  244.      *   output file is described by il2, ie2,
  245.      *   ll2, le2.
  246.      *
  247.      *   You can shrink the input image area
  248.      *   by using either the averaging, median,
  249.      *   or corner method.
  250.      *
  251.      *******************************************/
  252.  
  253. shrink_image_array(in_name, out